package actors

import akka.actor.typed.scaladsl.Behaviors
import akka.actor.typed.{ActorRef, Behavior, PostStop}
import akka.stream.Materializer
import dao.MissionDao
import implicits.Implicits._
import org.apache.commons.io.FileUtils
import org.joda.time.DateTime
import play.api.libs.json.{JsValue, Json}
import tool.Tool
import utils.Utils

import java.io.File
import javax.inject._
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.{ExecutionContext, Future}
import scala.concurrent.duration._
import models.Tables._

/**
 * Created by yz on 13/4/2020
 */
object UpdateMissionActor {

  sealed trait Message

  case object Start extends Message

  object TryUpdate extends Message

  def boot(userId: Int, out: ActorRef[JsValue], beforeMissions: List[MissionRow])(implicit missionDao: MissionDao): Behavior[Message] =
    Behaviors.receive[Message] { case (context, message) =>
      message match {
        case TryUpdate =>
          val currentMissions = Utils.execFuture(missionDao.selectAll(userId))
          if (currentMissions.size != beforeMissions.size) {
            out ! Utils.getJsonByTs(currentMissions)
          } else {
            val b = currentMissions.zip(beforeMissions).forall {
              case (currentMission, beforeMission) =>
                currentMission.id == beforeMission.id && currentMission.state == beforeMission.state
            }
            if (!b) {
              out ! Utils.getJsonByTs(currentMissions)
            }
          }
          boot(userId, out, currentMissions)
      }
    }.receiveSignal {
      case (context, PostStop) =>
        Behaviors.stopped
    }

  def apply(userId: Int, replyTo: ActorRef[JsValue])(implicit missionDao: MissionDao
  ): Behavior[Message] = {
    Behaviors.setup { implicit context =>
      Behaviors.withTimers { timers =>
        timers.startTimerAtFixedRate(TryUpdate, 3.seconds)
        boot(userId, replyTo, List[MissionRow]())
      }
    }
  }

}